package com.ssky.bean.validator.proxy;

import com.ssky.bean.validator.core.IMethodCheckerHandler;
import com.ssky.bean.validator.core.VldConstants;
import javassist.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Author: ssky
 * @Date: 2021/07/26
 * @Description:
 */
public class MethodCheckerHandlerCreator {
    public static final Logger L = LoggerFactory.getLogger(MethodCheckerHandlerCreator.class);

    //    private static final String NLine = "\n";
    private static final String START_CLASS_NAME = "MethodChecker$";
    private static final String ParamName = "bean";
    private static final ClassPath classPath = new ClassClassPath(IMethodCheckerHandler.class);
    private static final String PackageStr = DynProxyImplPackagePosition.class.getPackage().getName();

    public MethodCheckerHandlerCreator() {
    }

    public IMethodCheckerHandler create(String ruleId, String mImport, String methodBody) throws Exception {
        CtClass impCtClass = null;
        ClassPool pool = new ClassPool(true);
        pool.insertClassPath(classPath);
        CtClass ctInterface = pool.getCtClass(IMethodCheckerHandler.class.getName());
        ruleId = ruleId.replace(".", "_").replace("-", "_");
        impCtClass = pool.makeClass(PackageStr + "." + START_CLASS_NAME + ruleId + VldConstants.Atomic_Long.getAndIncrement());
        impCtClass.addInterface(ctInterface);

        pool.importPackage("java.util.*");
        pool.importPackage("com.ssky.bean.validator.core.IValidatorContext");


        if (mImport != null && !mImport.trim().equals("")) {
            mImport = mImport.replaceAll("\\s", "").replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "").replaceAll("\t", "");
            for (String pkg : mImport.split(";")) {
                if (!pkg.trim().equals("")) {
                    pkg = pkg.replace(".*", "");
                    pool.importPackage(pkg);
                }
            }
        }

        String methodStr = genMthodStr(methodBody);

        CtMethod method = null;
        try {
            method = CtNewMethod.make(methodStr, impCtClass);
            impCtClass.addMethod(method);
        } catch (CannotCompileException e) {
            L.error("impCtClass.addMethod(method) occur exception ,methodStr --->" + methodStr, e);
            throw e;
        }
        Class<IMethodCheckerHandler> clazz = null;
        try{

            clazz = (Class<IMethodCheckerHandler>) impCtClass.toClass(ValidatorClassLoader.getCustomCLoader(MethodCheckerHandlerCreator.class));
        }catch (Exception e){
            L.error("impCtClass.toClass occur exception ,methodStr --->" + methodStr, e);
        }


        // todo   清除javassist缓存
        IMethodCheckerHandler handler = clazz.newInstance();
        return handler;
    }

    private String genMthodStr(String methodBody) {
        String methodStr = "public boolean " + IMethodCheckerHandler.Method_Name + " ( Object " + ParamName + ",IValidatorContext context )";
        methodStr = methodStr + methodBody;
        return methodStr;
    }
}